package com.bw.product.initiate;

import com.bw.common.redis.service.RedisService;

import com.bw.product.domain.PmsSkuInfo;
import com.bw.product.service.PmsSkuInfoService;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;

import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;


import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Component
public class projectInitiate implements ApplicationRunner {


    @Autowired
    private PmsSkuInfoService pmsSkuInfoService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedisService redisService;

    private static final String LOCK_PREFIX = "stock:lock:";

    private static final String CART_ITEM = "inventory:num:";

    private static final long LOCK_TIMEOUT = 3000;

    private boolean tryLock(String lockKey, long timeout) {
        return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, "1", timeout, TimeUnit.MILLISECONDS));
    }


    private void releaseLock(String lockKey) {
        redisTemplate.delete(lockKey);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {


        //获取库存数据
        PmsSkuInfo pmsSkuInfo = new PmsSkuInfo();

        List<PmsSkuInfo> pmsSkuInfos = pmsSkuInfoService.selectPmsSkuInfoList(pmsSkuInfo);


        //预热到redis中
        pmsSkuInfos.forEach(newPmsSkuInfo -> {

            String lockKey = LOCK_PREFIX + newPmsSkuInfo.getSkuId();

            String key = CART_ITEM + newPmsSkuInfo.getSkuId();

            boolean locked = tryLock(lockKey, LOCK_TIMEOUT);
            if (!locked) {
                return;
            }
            try {

                Long num = (long) (new Random().nextInt(90) + 10);

                Integer inventory = Math.toIntExact(newPmsSkuInfo.getInventory());

                redisService.setCacheObject(key, inventory , num, TimeUnit.HOURS);

            } finally {
                releaseLock(lockKey);
            }


        });
    }
}
